package com.fancy.application.sys.permission.service.impl;

import cn.hutool.core.util.StrUtil;
import com.fancy.application.common.utils.RedisUtil;
import com.fancy.application.common.utils.UserUtil;
import com.fancy.application.sys.permission.entity.SysPermissionResCategory;
import com.fancy.application.sys.permission.entity.SysPermissionUrl;
import com.fancy.application.sys.permission.service.ISysPermissionMatcher;
import com.fancy.application.sys.permission.service.ISysPermissionResCategoryService;
import com.fancy.application.sys.permission.service.ISysPermissionUrlService;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.util.AntPathMatcher;
import org.apache.shiro.util.PatternMatcher;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 加载权限信息
 */
@Log4j2
@Component("sysPermissionMatcher")
public class SysPermissionMatcher implements CommandLineRunner, ISysPermissionMatcher {
    private final String module_key = "moduleKey";      //模块存入redis的key值

    @Resource
    private ISysPermissionResCategoryService sysPermissionResCategoryService;
    @Resource
    private ISysPermissionUrlService sysPermissionUrlService;
    @Resource
    private RedisUtil redisUtil;



    /**
     *  暂时只控制url权限，不控制api权限
     * @param uri
     * @param method
     * @return
     */
    public  Boolean  doMatch(String uri,String method){
        PatternMatcher patternMatcher = new AntPathMatcher();
        Boolean urlAuthFlag = Boolean.TRUE;
        if(StrUtil.isNotEmpty(uri)){
            List<SysPermissionResCategory> sysPermissionResCategories = (List<SysPermissionResCategory>) redisUtil.get(module_key);
            Optional<SysPermissionResCategory> optional = sysPermissionResCategories.stream()
                    .filter(sysPermissionResCategory -> StrUtil.startWith(uri,sysPermissionResCategory.getFdModulePath())).findFirst();
            if(optional.isPresent()){
                SysPermissionResCategory sysPermissionResCategory = optional.get();
                String fdModuleId = sysPermissionResCategory.getFdId();
                List<SysPermissionUrl> urls = (List<SysPermissionUrl>) redisUtil.get(getModuleKeyById(fdModuleId));
                List<SysPermissionUrl> parentUrlList = urls.stream()
                        .filter(sysPermissionUrl -> StrUtil.isEmpty(sysPermissionUrl.getFdParentId())).collect(Collectors.toList());
                Optional<SysPermissionUrl> parentOptional =  urls.stream().filter(sysPermissionUrl ->
                        patternMatcher.matches(sysPermissionUrl.getFdPath(), uri)).findFirst(); //查找父类的url验证，如果验证失败，则直接失败
                if(parentOptional.isPresent()){
                    SysPermissionUrl parentUrl = parentOptional.get();
                    if(!UserUtil.isPermitted(parentUrl.getFdExpression())) return false;
                    String fdParentId = parentUrl.getFdParentId();
                    List<SysPermissionUrl> childUrlList =  parentUrlList.stream().filter(sysPermissionUrl ->
                            StrUtil.equals(sysPermissionUrl.getFdParentId(),fdParentId)
                            ).collect(Collectors.toList());
                    Optional<SysPermissionUrl>  childOptional =  childUrlList.stream().filter(sysPermissionUrl ->
                            patternMatcher.matches(sysPermissionUrl.getFdPath(), uri)&&StrUtil.equals(sysPermissionUrl.getFdMethod(),method)
                    ).findFirst(); //查找子类的url验证，如果验证失败，则失败
                    if(childOptional.isPresent()){
                        SysPermissionUrl childUrl = parentOptional.get();
                        urlAuthFlag = UserUtil.isPermitted(parentUrl.getFdExpression());
                    }
                }
            }
        }
        return urlAuthFlag;
    }

    @Override
    public void run(String... args) {
        //启动加载模块信息和url信息
        List<SysPermissionResCategory> sysPermissionResCategories  = sysPermissionResCategoryService.list();
        redisUtil.delKeys(module_key);
        redisUtil.set(module_key,sysPermissionResCategories);
        //再加载url权限数据
        List<SysPermissionUrl> urls = sysPermissionUrlService.list();
        sysPermissionResCategories.forEach(sysPermissionResCategory -> {
            List<SysPermissionUrl> moduleUrls = urls.stream().filter(sysPermissionUrl ->
                    StrUtil.equals(sysPermissionUrl.getFdModuleId(),sysPermissionResCategory.getFdId()))
                    .collect(Collectors.toList());
            String fdId = sysPermissionResCategory.getFdId();
            redisUtil.set(getModuleKeyById(fdId),moduleUrls);
        });
        log.info("模块列表加载成功!");
    }

    private String getModuleKeyById(String id){
        return this.module_key+"#"+id;
    }
}
